package com.dnzx.socket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dnzx.exception.BizException;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {

    private static final Logger LOGGER = LoggerFactory.getLogger(SocketServer.class);

    private static ServerSocket serverSocket;
    // private ListeningThread listeningThread;
    private static Socket socket;
    private static boolean mainSwitch = true;

    private static final byte[] GET_EPC = new byte[]{(byte) 0xBB, 0x19, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x06, 0x2E, 0x0D, 0x0A};


    public SocketServer(int port, int poolsize) {
        //InputStream is = null;
        //OutputStream os = null;
        DataInputStream dis = null;
        // DataOutputStream dos = null;
        try {
            serverSocket = new ServerSocket(port);
            serverSocket.setReuseAddress(true);
            //改用单线程，socket静态化，实现同一通道统一调用，后续再根据需求改用多线程用map实现多客户端共享
//            listeningThread = new ListeningThread( serverSocket, poolsize);
//            listeningThread.start();
            while (true) {//持续等待连接(客户端主动断开后重连)
                socket = serverSocket.accept();
                socket.setSoTimeout(12000);//客户端默认会发送心跳包，间隔时间为10s
//            is = socket.getInputStream();
//            os = socket.getOutputStream();
                dis = new DataInputStream(socket.getInputStream());
                // dos = new DataOutputStream(socket.getOutputStream());

                int length = dis.available();
                byte[] bytes = new byte[length]; //
//                StringBuffer sb = new StringBuffer();
                try {
                    m:
                    while (true) {
                        if (mainSwitch) {
//                            System.out.println("in");
                            if (dis != null && dis.read(bytes) != -1) {
//                                sb.append(bytesToHexString(bytes));
//                                if (dis.available() == 0) { //一个请求
//                                    System.out.println(sb);
//                                    String[] reqs = sb.toString().split("1b32");
//                                    if (reqs == null || reqs.length == 0) {
                                       // System.out.println("解析错误");
//                                    }
                                    //String req = reqs[0];
                                    //清空
//                                    sb.setLength(0);
//                                }
                            }
                        } else {
//                            System.out.println("sleep");
                            Thread.sleep(1000);
                        }
                    }
                } catch (IOException e) {
                    LOGGER.error("IOException:", e.getMessage(), e);
                }
            }
        } catch (Exception e) {
            LOGGER.error("create server:", e.getMessage(), e);
        } finally {
            if (dis != null) {
                try {
                    dis.close();
                } catch (Exception ex) {
                    LOGGER.error("inputstream close:", ex.getMessage(), ex);
                }
            }
//            if (dos != null) {
//                try {
//                    dos.close();
//                } catch (Exception ex) {
//                    LOGGER.error("outputstream close:", ex.getMessage(), ex);
//                }
//            }
            if (socket != null) {
                try {
                    socket.close();
                    socket = null;
                } catch (Exception ex) {
                    LOGGER.error("socket close:", ex.getMessage(), ex);
                }
            }
        }
    }

    public static synchronized String getEpc() throws BizException {
        mainSwitch = false;
        String mac = "";
        DataInputStream dis = null;
        DataOutputStream dos = null;
        int length = 0;
        try {
            if (socket == null || socket.isClosed()) {
                new Thread() {
                    @Override
                    public void run() {
                        try {
                            socket = serverSocket.accept();
                        } catch (IOException e) {
                            LOGGER.error("读写器连接异常：" + e.getMessage(), e);
                        }
                    }
                }.start();
                Thread.sleep(3000);//等待连接3s(超时时间)
            }
            if(socket == null || socket.isClosed()){
                throw new BizException("请先连接读写器");
            }
            dis = new DataInputStream(socket.getInputStream());
            dos = new DataOutputStream(socket.getOutputStream());
            dos.write(GET_EPC);
            dos.flush();
            Thread.sleep(500);
            for ( int i=0;i<3;i++){
                length = dis.available();
                //TODO 修改日志级别
                LOGGER.error("读取时间测试：第"+i+"次，数据长度："+length);
                if(length > 0){
                    break;
                }
                Thread.sleep(500);
            }

        } catch (IOException e) {
            LOGGER.error("服务端接受连接异常：" + e.getMessage(), e);
            throw new BizException("读写器连接错误，请重连");
        } catch (InterruptedException e) {
            LOGGER.error("线程睡眠异常：" + e.getMessage(), e);
            throw new BizException("系统繁忙，请稍后重试");
        }

        byte[] bytes = new byte[length]; //
        StringBuffer sb = new StringBuffer();
        try {
            while (dis.read(bytes) != -1) {
                sb.append(bytesToHexString(bytes));
                if (dis.available() == 0) { //一个请求
//                    System.out.println(sb);
                    String[] reqs = sb.toString().split("1b32");
                    if (reqs == null || reqs.length == 0) {
                        throw new BizException("读取错误");
                    }
                    for (int i = 0; i < reqs.length; i++) {
                        String req = reqs[i];
                        if (!req.startsWith("bb") || !"99".equals(req.substring(2, 4))) {
                            continue;
                        }
                        if (req.length() != 54) {
                            throw new BizException("标签不合法");
                        }
                        mac = req.substring(12, 36);
                        break;
                    }
                    //清空
                    //  sb.setLength(0);
                    return mac;
                }
            }

        } catch (IOException e) {
            LOGGER.error("读取操作异常：" + e.getMessage(), e);
            throw new BizException("系统繁忙，请稍后重试");
        } finally {
            mainSwitch = true;
            if (dis != null) {
                try {
                    dis.close();
                } catch (Exception ex) {
                    LOGGER.error("inputstream close:", ex.getMessage(), ex);
                }
            }
            if (dos != null) {
                try {
                    dos.close();
                } catch (Exception ex) {
                    LOGGER.error("outputstream close:", ex.getMessage(), ex);
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                    socket = null;
                } catch (Exception ex) {
                    LOGGER.error("socket close:", ex.getMessage(), ex);
                }
            }
        }
        return mac;

    }

    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }


}
